.386p
.model FLAT

.data
	X0	dd ?
	Y0	dd ?
	X1	dd ?
	Y1	dd ?
	LineColor db ?

_g_targetcolor	dd	0
_g_imagebuffer	dd	0

.code

public _g_targetcolor
public _g_imagebuffer

public  drawline_
public  pastepanel_
public  copylines_
public  complexlines_
public  fourlongs_
public  twolongs_
public  quickrwpanel_
public  quickcypanel_
public  bufferpaste_
public  bufferclear_
public  buffer320to352_
public  bufferbytexchg_
public  bufferbytepaste_
public  copysmackbuffer_
public  buffercopylongs_
public  bufferpastehmeter_
public  bufferpastelmeter_
public  bufferbytepastewa_
public  bufferpastesquare_
public  bufferbyteyankfromscr_


; ---------------------------------------------------------------------
; Line-drawing macros
; ---------------------------------------------------------------------

LINE1 macro MOVE_LEFT
	local lineloop,MoveXCoord,Line1End

	mov	ecx,ebx	; # of pixels (ebx=DeltaX)
	jecxz Line1End	; done if no more pixels
	shl	esi,1	; DY*2
	mov	edx,esi	; edx = error term
	sub	edx,ebx	; error term=DY*2-DX
	shl	ebx,1	; DX*2
	sub	esi,ebx	; DY*2-DX*2
	add	ebx,esi	; DY*2
	mov	al,[LineColor]

lineloop:
;
; Time to advance Y-Coord?
;
	and edx,edx	; check if error term is negative
	js MoveXCoord	; Yes, stay at same Y-coord
;
; advance y-coord
;
	add	edi,[ebp+12]	; Add 1 screen-width to offset
	add	edx,esi	; adjust error term
	sub	edx,ebx
;
; advance x-coord
;
MoveXCoord:
	add	edx,ebx	; increment error term
if MOVE_LEFT
	dec	edi
else
	inc	edi
endif
;
; write pixel
;
	mov	[edi],al
	dec	ecx
	jnz	lineloop
Line1End:
ENDM

LINE2 macro MOVE_LEFT
local lineloop,MoveYCoord,line2end

	mov	ecx,esi	; # of pixels (esi=DeltaY)
	jecxz line2end	; done if no more pixels
	shl	ebx,1	; DX*2
	mov	edx,ebx	; edx = error term
	sub	edx,esi	; error term=DX*2-DY
	shl	esi,1	; DY*2
	sub	ebx,esi	; DX*2-DY*2
	add	esi,ebx	; DX*2
	mov	al,[LineColor]

lineloop:
;
; Time to advance X-Coord?
;
	and edx,edx	; check if error term is negative
	js MoveYCoord	; Yes, stay at same X-coord
;
; advance X-coord
;
if MOVE_LEFT
	dec	edi
else
	inc	edi
endif
	add	edx,ebx	; adjust error term
	sub	edx,esi
;
; advance Y-coord
;
MoveYCoord:
	add	edx,esi	; increment error term
	add	edi,[ebp+12]	; Add 1 screen-width to offset
;
; write pixel
;
	mov	[edi],al
	dec	ecx
	jnz	lineloop
line2end:
ENDM


;
; copybuffer(to,from)
; 
; copysmackbuffer(to,from,numlines)
;eax,edx,ebx,ecx 
copysmackbuffer_ proc
	push	edi
	push	esi
	mov	edi,eax
	mov	esi,edx
	mov	ecx,320	; 320 width hard coded :P
	shr 	ecx,2     ;Movin' longs
copyline:
	push 	ecx
	repe 	movsd
	add 	edi,32
	add 	esi,32
	pop	ecx
	dec	ebx
	jnz	copyline
	pop	esi
	pop	edi
	ret
copysmackbuffer_ endp


;copysmackbuffer_ proc
;	mov	ebx,eax
;	mov	ecx,200	; 200 lines hard coded :P
;copyline:
;POFF=0
;REPT 352/4
;	mov	eax,[edx+POFF]	; fetch a DWORD of data
;
;	mov	[ebx+POFF],eax	; store it
;
;POFF=POFF+4
;ENDM
;	add	edx,352
;	add	ebx,352
;	dec	ecx
;	jnz	copyline
;	ret
;copysmackbuffer_ endp
;
; ------------------------------------------------------------------------
; drawline(eax=x0,edx=y0,ebx=x1,ecx=y1,esp+8=buffer,esp+12=bufferwidth,
;		  esp+16=color)
; ------------------------------------------------------------------------

drawline_ proc
	push	ebp
	mov	ebp,esp
	push	esi
	push edi
	mov	esi,ecx
	sub	esi,edx	; calculate delta y
	jns	PositiveCase
;
; negative case, reverse coords
;
	mov	[X1],eax
	mov	[Y1],edx
	mov	[X0],ebx
	mov	[Y0],ecx
	neg	esi	; Make positive DY
	jmp	CalcStartAddress

PositiveCase:
	mov	[X0],eax
	mov	[Y0],edx
	mov	[X1],ebx
	mov	[Y1],ecx
;
; Calculate starting address
;
CalcStartAddress:
	mov	eax,[ebp+16]	; save off color first
	mov	[LineColor],al
	mov	eax,[Y0]
	mov	ebx,[ebp+12]	; width of display buffer
	mul	ebx	; multiply Y0*width
	add	eax,[X0]	; add X0
	add	eax,[ebp+8]	; finally add actual buffer start
	mov	edi,eax
;	
; Calculate delta-x
;
	mov	ebx,[X1]
	sub	ebx,[X0]
;
; Determine correct octant
;
	js	NegDeltaX
	cmp	ebx,esi	; remember, esi contains Delta-Y
	jb	Octant1
;
; DeltaX >= DeltaY >= 0 (Octant 0?)
;
	LINE1 0
	jmp	LineDone
;
; DeltaY > DeltaX >= 0
;
Octant1:
	LINE2 0
	jmp LineDone

NegDeltaX:
	neg	ebx	; |DeltaX|
	cmp	ebx,esi
	jb	Octant2
;
; |DeltaX| >= DeltaY, DeltaX<0
;
	LINE1 1
	jmp LineDone
;
; |DeltaX| < DeltaY, DeltaX<0
;
Octant2:
	LINE2 1

LineDone:
	pop	edi
	pop	esi
	pop	ebp
	ret
drawline_ endp


; With alpha
; bufferbytepastewa(to,from,widthheight,alpha) 
;eax,edx,ebx,ecx 
bufferbytepastewa_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov edx,ecx
	mov ecx,ebx;
	and ecx,0000FFFFh
	and edx,000000FFh ;Alpha color
	shr ebx,16
bbpaste1:
    push ebx     ; Save width on stack
next_on_line1:
	mov	al,byte ptr [esi]
    cmp al,dl
	je next_pixel1
	mov	byte ptr [edi],al
next_pixel1:
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_line1
	pop ebx     ;Restore width 
	add	edi,352
	sub edi,ebx
	dec	ecx
	jnz  bbpaste1
	pop	edi
	pop	esi
	ret
bufferbytepastewa_ endp

; bufferbyteyankfromscr(to,from,widthheight,offset)
;eax,edx,ebx,ecx
bufferbyteyankfromscr_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov ecx,ebx;
	and ecx,0000FFFFh
	shr ebx,16
bbpastefs:
    push ebx     ; Save width on stack
next_on_linefs:
	mov	al,byte ptr [esi]
	mov	byte ptr [edi],al
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_linefs
	pop ebx     ;Restore width 
	;add esi,edx ;Bring source and dest up to real length
	add	esi,352
	sub esi,ebx
	dec	ecx
	jnz  bbpastefs
	pop	edi
	pop	esi
	ret
bufferbyteyankfromscr_ endp

; bufferbytepaste(to,from,widthheight,offset)
;eax,edx,ebx,ecx
bufferpastelmeter_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov 	edx,ecx
	mov 	ecx,ebx;
	and 	ecx,0000FFFFh
	shr 	ebx,16
bbpaste_meter:
	push 	edx     ; Save extra on stack
	push 	ebx     ; Save width on stack

next_on_line_meter:
	mov	al,byte ptr [esi]
	mov	byte ptr [edi],al
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_line_meter

	cmp 	edx,0
	jz 	continue_meter

extra_black:
	mov	byte ptr [edi],0
	inc	edi
	dec 	edx
	jnz 	extra_black

continue_meter:
	pop 	ebx     ;Restore width 
	pop 	edx     ;Restore extra

	add 	esi,edx
	add	edi,352 ;Bring source and dest up to real length
	sub 	edi,ebx
	sub 	edi,edx

	dec	ecx
	jnz  	bbpaste_meter
	sub	edi,364 ;go up 1 line, back 12
	add	edi,ebx ;then add width 
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi 
	mov	byte ptr [edi],0
	inc	edi 
	mov	byte ptr [edi],0
	inc	edi 
	mov	byte ptr [edi],0
	inc	edi 
	mov	byte ptr [edi],0
	pop	edi
	pop	esi
	ret
bufferpastelmeter_ endp

; bufferbytelpaste(to,from,widthheight,offset)
;eax,edx,ebx,ecx
bufferpastehmeter_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov 	edx,ecx
	mov 	ecx,ebx;
	and 	ecx,0000FFFFh
	shr 	ebx,16
bbpaste_hmeter:
	push 	edx     ; Save extra on stack
	push 	ebx     ; Save width on stack

next_on_line_hmeter:
	mov	al,byte ptr [esi]
	mov	byte ptr [edi],al
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_line_hmeter

	cmp 	edx,0
	jz 	continue_hmeter

extra_hblack:
	mov	byte ptr [edi],0
	inc	edi
	dec 	edx
	jnz 	extra_hblack

continue_hmeter:
	pop 	ebx     ;Restore width 
	pop 	edx     ;Restore extra

	add 	esi,edx
	add	edi,352 ;Bring source and dest up to real length
	sub 	edi,ebx
	sub 	edi,edx

	dec	ecx
	jnz  	bbpaste_hmeter
	cmp	ebx,88
	jne	done_hmeter
	sub	edi,357 ;go up 1 line, back 5 
	add	edi,ebx ;then add width and paste in 3 black 
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0
	inc	edi
	mov	byte ptr [edi],0

done_hmeter:
	pop	edi
	pop	esi
	ret
bufferpastehmeter_ endp

; bufferbytepaste(to,from,widthheight,offset)
;eax,edx,ebx,ecx
bufferbytepaste_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov edx,ecx
	mov ecx,ebx;
	and ecx,0000FFFFh
	shr ebx,16
bbpaste:
    push ebx     ; Save width on stack
next_on_line:
	mov	al,byte ptr [esi]
	mov	byte ptr [edi],al
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_line
	pop ebx     ;Restore width 
	add esi,edx ;Bring source and dest up to real length
	;add edi,edx
	add	edi,352
	sub edi,ebx
	dec	ecx
	jnz  bbpaste
	pop	edi
	pop	esi
	ret
bufferbytepaste_ endp


;
; bufferclear_(buffer,buffersize)
;eax,edx,ebx,ecx
bufferclear_ proc
	push	edi
	push    ecx
	mov	edi,eax ;Destionation
	mov	ecx,edx ;size
	shr ecx,2   ;divide by 4
	xor eax,eax
	start_clr:
    mov [edi],eax
	add edi,4
	dec ecx
	jnz start_clr
	pop	ecx
	pop	edi
	ret
bufferclear_ endp

; buffer320to352(to,from)
;eax,edx,ebx,ecx  ;NOTE!! This functions assumes you are copying
                  ;an amount divisible by 4!!!
				  ;and that you are copying a 320X200 length onto a 352X200
				  ;buffer. 
buffer320to352_ proc
	push	esi
	push	edi
	push    ecx
	push    ebx

	mov	edi,eax
	;add edi,16
	mov	esi,edx
	mov ebx,200 

next_320_line:
	mov ecx,320
	shr ecx,2     ;Movin' longs
	repe movsd    ;Do it
	dec ebx
	jz copy_320_fin
	add edi,32     ; move up to next 352 line
	jmp next_320_line
	
copy_320_fin:
    pop     ebx
	pop     ecx
	pop     edi
	pop     esi
	ret
buffer320to352_ endp

; buffercopylongs(to,from,length)
;eax,edx,ebx,ecx  ;NOTE!! This functions assumes you are copying
                  ;an amount divisible by 4!!!
buffercopylongs_ proc
	push	esi
	push	edi

	mov	edi,eax
	mov	esi,edx
	mov ecx,ebx
	shr ecx,2

	repe movsd

	pop     edi
	pop     esi
	ret
buffercopylongs_ endp

;
; bufferpastesquare(ul,ur,ll,lr)
;eax,edx,ebx,ecx
bufferpastesquare_ proc
	push	esi
	push	edi
	push    ecx

;Upper left horizontal line
	mov edi,_g_imagebuffer
	mov esi,_g_targetcolor
	add edi,eax
	mov al, byte ptr [esi]

;Upper left vertical line
	mov [edi + 352],al   ;Squares always 2 down veritcally
	mov [edi + 704],al   ;Squares always 2 down veritcally

	mov ecx,1   ;Squares always 8 - 4 - 8 horizontally 
	repe movsd


;Upper right horizontal line
	mov edi,_g_imagebuffer
	mov esi,_g_targetcolor
	add edi,edx
	mov ecx,1   ;Squares always 8 - 4 - 8 horizontally 
	repe movsd
	dec edi
	mov [edi + 352],al   ;Squares always 2 down veritcally
	mov [edi + 704],al   ;Squares always 2 down veritcally


;Lower left horizontal line
	mov edi,_g_imagebuffer
	mov esi,_g_targetcolor
	add edi,ebx
	mov [edi - 352],al   ;Squares always 2 down veritcally
	mov [edi - 704],al   ;Squares always 2 down veritcally
	mov ecx,1   ;Squares always 8 - 4 - 8 horizontally 
	repe movsd

;Lower right horizontal line
    pop ecx
	mov edi,_g_imagebuffer
	mov esi,_g_targetcolor
	add edi,ecx
	mov ecx,1   ;Squares always 8 - 4 - 8 horizontally 
	repe movsd
	dec edi
	mov [edi - 352],al   ;Squares always 2 down veritcally
	mov [edi - 704],al   ;Squares always 2 down veritcally

	pop	edi
	pop	esi
	ret
bufferpastesquare_ endp

;
; bufferpaste(to,from,width,height)
;eax,edx,ebx,ecx
bufferpaste_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
bpaste:
    push ebx     ; Save width on stack
nextb_on_line:
	mov	eax,[esi]
	mov	[edi],eax
	add	esi,4
	add	edi,4
	sub	ebx,4
	jnz	nextb_on_line
	pop ebx     ;Restore width 
	add	edi,352
	sub	edi,ebx
	dec	ecx
	jnz  bpaste
	pop	edi
	pop	esi
	ret
bufferpaste_ endp

; bufferbytexchg(to,from,widthheight,aliasdirection)
;
;aliasdirection: if its 0 black bits from the to are not xchged to the from
;                if its 1 black bits from the from are not xchged to the to
;eax,edx,ebx,ecx
bufferbytexchg_ proc
	push	esi
	push	edi
	mov	edi,eax
	mov	esi,edx
	mov edx,ecx  ;alias direction
	mov ecx,ebx; 
	and ecx,0000FFFFh
	shr ebx,16
bbpaste2:
    push ebx     ; Save width on stack
next_on_line2:
	mov	al,byte ptr [esi]
	mov	ah,byte ptr [edi]
    	cmp dx,0
	jne to_2_from
	cmp al,0
	je other_direction
to_2_from:
    mov byte ptr [edi],al
other_direction:
    cmp dx,1
	jne from_2_to
	cmp ah,0
	je nexttoxchg
from_2_to:
    mov byte ptr [esi],ah
nexttoxchg:
	inc	esi
	inc	edi
	dec	ebx
	jnz	next_on_line2
	pop ebx     ;Restore width 
	;add esi,edx ;Bring source and dest up to real length
	;add edi,edx
	add	edi,352
	sub edi,ebx
	dec	ecx
	jnz  bbpaste2
	pop	edi
	pop	esi
	ret
bufferbytexchg_ endp

copylines_ proc
copylinex:
	push 	ecx
	repe 	movsd
	add 	edi,32
	pop	ecx
	dec	eax
	jnz	copylinex
	ret
copylines_ endp

complexlines_ proc
complexline:
	mov  eax,[esi]
	cmp  byte ptr [edx],01h ;01s are longs that have zeros in all bytes
	je   move_alongx
	cmp  byte ptr [edx],02h ;02s are longs that have zeros in some bytes
	je   complex_longx
	mov  [edi],eax  ;Its 01, a real control panel long. Put it all in
	jmp  move_alongx

move_alongx:
	add  esi,4  ;Move along same line
	add  edi,4
return_from_complexx:
	inc  edx
	sub  ebx,4
	jnz  complexline
	mov  ebx,320
	add  edi,32 ;move to next line
	dec  ecx
	jnz  complexline
	ret

complex_longx: 	;A long with zeros in less than all four bytes
 	      	;Not elegant, but trying to keep it simple.

byte0x:
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on1x
	mov  [edi],al  ;Over write the byte
go_on1x:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on2x
	mov  [edi],al
go_on2x:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on3x
	mov  [edi],al
go_on3x:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_backx
	mov  [edi],al
go_backx:
	inc  esi 
	inc  edi
	jmp  return_from_complexx
complexlines_ endp


;four longs on the line - 2 in the front and 2 at the end

fourlongs_ proc
	push ebx
	mov  ebx,1
ruler:  ;ruler
	cmp  ecx,0
	je   go_homez  ;gohomez
	cmp  ebx,1
	je   check_byte ;checkbyte
	cmp  ebx,2
	je   check_byte ;checkbyte
	cmp  ebx,3
	je   move_ptrsup ;moveptrsup
	cmp  ebx,79
	je   check_byte ;checkbyte
	cmp  ebx,80
	je   check_byte ;checkbyte
	cmp  ebx,81
	je   back_toruler ;backtoruler
move_ptrsup:  ;moveptrsup
	add  esi,304
	add  edi,304
	add  edx,76
	add  ebx,76
	jmp  ruler ;ruler
back_toruler: ;backtoruler
	dec  ecx
	mov  ebx,1
	add  edi,32
	jmp  ruler ;ruler
check_byte:   ;checkbyte
	mov  eax,[esi]
	cmp  byte ptr [edx],01h ;01s are longs that have zeros in all bytes
	je   move_alongz      	;NOTE this should never happen! movealongz
	cmp  byte ptr [edx],02h ;02s are longs that have zeros in some bytes
	je   complex_longz      ;complexlongz
	mov  [edi],eax  ;Its 01, a real control panel long, put it all in
	jmp  move_alongz  ;movealongz

move_alongz:  ;movealongz
	add  esi,4  ;Move along same line
	add  edi,4
	inc  edx
	add  ebx,1
	jmp  ruler ;ruler

complex_longz: 	;A long with zeros in less than all four bytes
 	      	;Not elegant, but trying to keep it simple.

byte0z:
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on1z
	mov  [edi],al  ;Over write the byte
go_on1z:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on2z
	mov  [edi],al
go_on2z:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on3z
	mov  [edi],al
go_on3z:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_backz
	mov  [edi],al
go_backz:
	inc  esi 
	inc  edi
	inc  edx
	add  ebx,1
	jmp  ruler
go_homez:
	pop ebx
;	add edi,32
	ret
fourlongs_ endp


;Two longs on a line - 1 in front and one at the end

twolongs_ proc
	push ebx
	mov  ebx,1
rulerq:
	cmp  ecx,0
	je   go_homeq
	cmp  ebx,1
	je   check_byteq
	cmp  ebx,2
	je   move_ptrsupq
	cmp  ebx,80
	je   check_byteq
	cmp  ebx,81
	je   back_torulerq
move_ptrsupq:
	add  esi,312
	add  edi,312
	add  edx,78
	add  ebx,78
	jmp  rulerq
back_torulerq:
	dec  ecx
	mov  ebx,1
	add  edi,32
	jmp  rulerq
check_byteq:
	mov  eax,[esi]
	cmp  byte ptr [edx],01h ;01s are longs that have zeros in all bytes
	je   move_alongq	;NOTE this should never happen!
	cmp  byte ptr [edx],02h ;02s are longs that have zeros in some bytes
	je   complex_longq
	mov  [edi],eax  ;Its 01, a real control panel long, put it all in
	jmp  move_alongq

move_alongq:
	add  esi,4  ;Move along same line
	add  edi,4
	inc  edx
	add  ebx,1
	jmp  rulerq

complex_longq: 	;A long with zeros in less than all four bytes
 	      	;Not elegant, but trying to keep it simple.

byte0q:
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on1q
	mov  [edi],al  ;Over write the byte
go_on1q:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on2q
	mov  [edi],al
go_on2q:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_on3q
	mov  [edi],al
go_on3q:
	inc  esi 
	inc  edi
	mov  al, byte ptr [esi]
	cmp  al,00h
	je   go_backq
	mov  [edi],al
go_backq:
	inc  esi 
	inc  edi
	inc  edx
	add  ebx,1
	jmp  rulerq
go_homeq:
	pop ebx
;	add edi,32
	ret
twolongs_ endp

;quickrwpanel(to,from,map)
;eax,edx,ebx,ecx

quickrwpanel_ proc
	push	esi
	push	edi
	mov	esi,edx ;Source
	mov	edi,eax ;Destination
	mov     edx,ebx ;Map
step1:  ;step 1 has 6 control panel lines to copy
	mov	eax,6
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
step2:	; step 2 has 6 complex lines in it
	add	edx,480 ;move map up to our present place
	mov     ecx,6	; how many lines we need to go through
	mov	ebx,320
	call	complexlines_
step3:  ; step 3 has 16 lines of 2 longs, jump over 76, 2 longs
	mov	ecx,16
	call	fourlongs_
step4:	; step 4 has 55 lines of 1 long, jump over 78, 1 long
	mov	ecx,55
	call	twolongs_
step5:	; step 5 just jumps over 68 lines
	add  edi, 23936
	add  esi, 21760
	add  edx, 5440
step6:	; step 6 has 7 complex lines in it
	mov     ecx,7
	call	complexlines_
step7:	; step 7 has 16 copylines
	mov	eax,16
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
step8:	; step 8 has 12 complex lines in it
	mov     ecx,12
	call	complexlines_
step9:	; step 9 has 14 copylines
	mov	eax,14
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
	pop	edi
	pop	esi
	ret
quickrwpanel_ endp
	
;quickcypanel(to,from,map)
;eax,edx,ebx,ecx

quickcypanel_ proc
	push	esi
	push	edi
	mov	esi,edx ;Source
	mov	edi,eax ;Destination
	mov     edx,ebx ;Map
step1c:  ;step 1 has 2 control panel lines to copy
	mov	eax,2
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
step2c:	; step 2 has 30 complex lines in it
	add	edx,160 ;move map up to our present place
	mov     ecx,30	; how many lines we need to go through
	mov	ebx,320
	call	complexlines_
step3c: ; step 3 just jumps over 100 lines
	add  edi, 35200
	add  esi, 32000
	add  edx, 8000
step4c: ; step 4 has 28 complex lines
	mov ecx,28
	mov ebx,320
	call complexlines_
step5c:	; step 5 has 28 copy lines
	mov	eax,28
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
step6c:	; step 6 has 10 complex lines in it
	add	edx,2240 ;move map up to where we are
	mov     ecx,10
	call	complexlines_
step7c:	; step 7 has 2 copylines
	mov	eax,2
	mov	ecx,320	; 320 width hard coded 
	shr 	ecx,2   ;Movin' longs
	call	copylines_
	pop	edi
	pop	esi
	ret
quickcypanel_ endp
       	

; pastepanel(to,from,map)
;eax,edx,ebx,ecx

pastepanel_ proc
	push	esi
	push	edi
	mov	esi,edx ;Source
	mov	edi,eax ;Destination
	mov edx,ebx ;Map
	mov ecx,200
	mov ebx,320
	;add edi,10h

ppaste:
	mov	eax,[esi]
	cmp byte ptr [edx],01h ;01s are longs that have zeros in all bytes
	je dont_put  
	cmp byte ptr [edx],02h ;02s are longs that have zeros in some bytes
	je  complex_long

	mov	[edi],eax          ;Its a real control panel long. Put it all in
	jmp move_along

dont_put:
    push bx

	mov	ax,word ptr [edi]    ;Ok, then grab from the screen and check it
	mov	bx,word ptr [edi+2] 
	cmp al,0
	jne not_zero1
	mov al,192		;Put in the flashing black
not_zero1:
	cmp ah,0
	jne not_zero2
	mov ah,192		;Put in the flashing black
not_zero2:
	cmp bl,0
	jne not_zero3
	mov bl,192		;Put in the flashing black
not_zero3:
	cmp bh,0
	jne done_check
	mov bh,192      ;Put in the flashing black
done_check:
	mov word ptr [edi],ax
	mov word ptr [edi+2],bx
	pop bx
move_along:
	add	esi,4  ;Move along same line
	add	edi,4
return_from_complex:
	inc edx
	sub ebx,4
	jnz	ppaste

	mov	ebx,320 ;Move to next line
	add	edi,352
	sub	edi,ebx
	dec	ecx
	jnz  ppaste

	pop	edi
	pop	esi
	ret

complex_long: 		;A long with zeros in less than all four bytes
 					;Not elegant, but trying to keep it simple.

byte0:
   mov al, byte ptr [esi]
   cmp al,00h
   je byte1
   mov [edi],al  ;Over write the byte
   jmp go_on1
byte1:
   cmp byte ptr [edi],00h ;Test if its 00
   jne go_on1             ;Don't write it
   mov byte ptr [edi],192 ;Change it to the flashing black
go_on1:
   inc esi 
   inc edi

   mov al, byte ptr [esi]
   cmp al,00h
   je byte2
   mov [edi],al
   jmp go_on2
byte2:
   cmp byte ptr [edi],00h ;Test if its 00
   jne go_on2             ;Don't write it
   mov byte ptr [edi],192 ;Change it to the flashing black
go_on2:
   inc esi 
   inc edi

   mov al, byte ptr [esi]
   cmp al,00h
   je byte3
   mov [edi],al
   jmp go_on3
byte3:
   cmp byte ptr [edi],00h ;Test if its 00
   jne go_on3             ;Don't write it
   mov byte ptr [edi],192 ;Change it to the flashing black
go_on3:
   inc esi 
   inc edi

   mov al, byte ptr [esi]
   cmp al,00h
   je byte4
   mov [edi],al
   jmp go_back
byte4:
   cmp byte ptr [edi],00h ;Test if its 00
   jne go_back             ;Don't write it
   mov byte ptr [edi],192 ;Change it to the flashing black

go_back:
   inc esi 
   inc edi
   jmp return_from_complex
pastepanel_ endp


end
